home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / break.arc / break.asm next >
Assembly Source File  |  1989-03-28  |  12KB  |  328 lines

  1. ******************************************************************************
  2. *                                                                            *
  3. *    break.asm  version 1.0 of 20 August 1988   (C) L.J.M. de Wit 1988       *
  4. *                                                                            *
  5. * This software may be used and distributed freely if not used commercially  *
  6. * and the originator (me) is mentioned.                                      *
  7. *                                                                            *
  8. ******************************************************************************
  9. *
  10. * NAME
  11. *    break - stop current program on receipt of interrupt character
  12. *
  13. * SYNTAX
  14. *    break [-e|-d|-z] [-i|-c<code>]
  15. *
  16. * DESCRIPTION
  17. *
  18. *    After installing break, any program can be interrupted.
  19. *    This is achieved by 'extending' the existing keyboard interrupt
  20. *    routine: after executing the old code the break character check
  21. *    is done.
  22. *
  23. *    The various flags have the following meaning:
  24. *       e(nable) : the current break character will end the program.
  25. *                  the code returned is -32, what seems to be the standard
  26. *                  value for programs interrupted by ^C in GEMDOS.
  27. *       d(isable): no actions are done; this restores the old behaviour
  28. *       z(ero)   : the current break character will be discarded (made 0)
  29. *                  in the input buffer; this can be used to disable ^C.
  30. *       i(nput)  : the break character is prompted for. Combinations with
  31. *                  shift, control and alternate keys are also allowed.
  32. *                  Useful for specifying the break character interactively.
  33. *       c(ode)   : specifies the break character as a hexadecimal code.
  34. *                  The hex code must follow the 'c' flag immediately.
  35. *                  Useful for specifying the break character from a script.
  36. *    Of the flags e,d and z only one should be used; e is the default.
  37. *    Also, of the flags i and c only one should be used; control-delete is
  38. *    the default. This is done on purpose; you can always change it to ^C
  39. *    if you want to (or whatever key you like).
  40. *     
  41. *    The break program can be reused indefinitely, because a next invocation
  42. *    is not made memory resident; it only modifies parameters in the first
  43. *    invocation (the resident one).
  44. *
  45. *    The program can be placed into the \AUTO folder to be installed
  46. *    automatically, or activated 'by hand'. If placed in the \AUTO folder, it
  47. *    should of course have a .PRG extension (break.prg); as \AUTO folder
  48. *    programs don't get arguments, the break will be enabled and the break
  49. *    character is control-delete in this case.
  50. *
  51. * BUGS/SHORTCOMINGS
  52. *    A nice extension would be the possibility to catch the interrupt from
  53. *    a user program; this could be achieved by using a new trap. As this
  54. *    implies restoring the old interrupt catch routine when the program
  55. *    exits, and maybe also core dumps could be added to the action of an
  56. *    (other) interrupt character, such a more general signal mechanism is
  57. *    not added (yet). Gives me time to think of a nice implementation 8-).
  58. *
  59. * JOKE
  60. *    Gimme a break, huh?!
  61. *
  62.  
  63.       module  break
  64.       section s.ccode
  65.  
  66. * character codes
  67. tab      equ   9
  68. lf       equ   10
  69. cr       equ   13
  70.  
  71. * GEMDOS & (X)BIOS stuff
  72. gemdos   equ   1
  73. bios     equ   13
  74. xbios    equ   14
  75. ptermres equ   $31
  76. setexc   equ   5
  77. cconws   equ   9
  78. crawcin  equ   7
  79. super    equ   $20
  80. pterm0   equ   0
  81. pterm    equ   $4c
  82. iorec    equ   14
  83.  
  84. * divers
  85. bpaglen  equ   $100
  86. textlen  equ   12
  87. datalen  equ   20
  88. bsslen   equ   28
  89. intrupt  equ   -32               * Code returned by interrupted programs
  90. curproc  equ   $602c             * Contains base page start of current process
  91.  
  92. * iorec struct offsets; the buffer ptr. itself has offset 0
  93. ibufsize equ 4
  94. ibufhead equ 6
  95. ibuftl   equ 8
  96. ibuflow  equ 10
  97. ibufhi   equ 12
  98.  
  99.  
  100. brkinit
  101.       move.l   4(sp),a0
  102.       adda.w   #$80,a0           * a0 points to argument string start
  103.       moveq.l  #0,d0
  104.       move.b   (a0)+,d0          * Get string length &
  105.       clr.b    (a0,d0.w)         * ensure '\0' termination
  106. nxtbyt
  107.       move.b   (a0)+,d0
  108.       beq      nxtdone           * '\0' char is end of string
  109.       cmp.b    #'A',d0
  110.       blt.s    arge
  111.       cmp.b    #'Z',d0
  112.       bgt.s    arge
  113.       or.b     #$20,d0           * Convert uppercase to lower
  114. arge
  115.       cmp.b    #'e',d0           * enable
  116.       bne.s    argd
  117.       st       enabled           * enabled = TRUE
  118.       bra.s    nxtbyt
  119. argd
  120.       cmp.b    #'d',d0           * disable
  121.       bne.s    argi
  122.       sf       enabled           * enabled = FALSE
  123.       bra.s    nxtbyt
  124. argi
  125.       cmp.b    #'i',d0           * input
  126.       bne.s    argc
  127.       move.l   a0,-(sp)
  128.       pea.l    inpmsg
  129.       move.w   #cconws,-(sp)
  130.       trap     #gemdos           * Prompt for break char
  131.       addq.l   #6,sp
  132.       move.w   #crawcin,-(sp)
  133.       trap     #gemdos           * Read the char
  134.       addq.l   #2,sp
  135.       move.l   d0,breakcode      * and store it
  136.       pea.l    retmsg
  137.       move.w   #cconws,-(sp)
  138.       trap     #gemdos           * Print a cr/lf
  139.       addq.l   #6,sp
  140.       move.l   (sp)+,a0
  141.       bra.s    nxtbyt
  142. argc
  143.       cmp.b    #'c',d0           * code of break char in hex
  144.       bne.s    argz
  145.       moveq.l  #0,d1             * d1 will contain the code
  146. argcnxt
  147.       move.b   (a0)+,d0
  148.       bne.s    argcnz            * Not end of arg string yet
  149.       move.l   d1,breakcode      * If end, store break char
  150.       bra      nxtdone           * and goto end of arg string interpretation
  151. argcnz
  152.       cmp.b    #' ',d0           * End of number found
  153.       beq.s    argcend
  154.       cmp.b    #tab,d0           * this one too
  155.       beq.s    argcend
  156.       cmp.b    #'0',d0           * Now follows a series of tests and
  157.       blt.s    userr             * conversions to find the hex digit's value.
  158.       cmp.b    #'a',d0
  159.       blt.s    argcnlc
  160.       sub.w    #32,d0            * convert lower case to upper
  161. argcnlc
  162.       cmp.b    #'F',d0
  163.       bgt.s    userr
  164.       cmp.b    #'9',d0
  165.       ble.s    argcnum
  166.       cmp.b    #'A',d0
  167.       blt.s    userr
  168.       subq.l   #7,d0             * Make up for diff between '9' and 'A'
  169. argcnum
  170.       sub.b    #'0',d0           * '0' is the base: 0
  171.       asl.l    #4,d1             * Multiply by 16
  172.       or.b     d0,d1             * OR in the 4 low digits of d0 into d1
  173.       bra.s    argcnxt
  174. argcend
  175.       move.l   d1,breakcode      * Store the break key code
  176.       bra      nxtbyt
  177. argz
  178.       cmp.b    #'z',d0
  179.       bne.s    argsep
  180.       st       zeroed            * Set the 'zeroed' flag
  181.       bra      nxtbyt
  182. argsep
  183.       cmp.b    #' ',d0           * Accept space
  184.       beq      nxtbyt
  185.       cmp.b    #tab,d0           * and tab
  186.       beq      nxtbyt
  187.       cmp.b    #'-',d0           * and hyphen as separators (not strictly)
  188.       beq      nxtbyt
  189. userr
  190.       pea.l    usemsg            * If error in arg string show usage message
  191.       move.w   #cconws,-(sp)
  192.       trap     #gemdos
  193.       addq.l   #6,sp
  194.       move.w   #1,-(sp)
  195.       move.w   #pterm,-(sp)
  196.       trap     #gemdos           * and terminate with error status
  197.  
  198. nxtdone
  199.       move.w   #1,-(sp)
  200.       move.w   #iorec,-(sp)
  201.       trap     #xbios
  202.       addq.l   #4,sp
  203.       move.l   d0,iop            * Save pointer to iorec struct
  204.       move.l   #-1,-(sp)
  205.       move.w   #$46,-(sp)
  206.       move.w   #setexc,-(sp)
  207.       trap     #bios
  208.       addq.l   #8,sp
  209.       move.l   d0,oldvec         * Save old keyboard interrupt vector
  210.       lea.l    breakey,a0
  211.       sub.l    a0,d0
  212.       move.l   d0,diff           * Difference between start addr of old and new
  213.       clr.l    -(sp)
  214.       move.w   #super,-(sp)
  215.       trap     #gemdos           * Supervisor mode
  216.       addq.l   #2,sp
  217.       move.l   d0,(sp)           * Save supervisor stack pointer on stack
  218.       lea.l    magic,a0          * a0 points to 'magic' string in this prog
  219.       move.l   diff,d0
  220.       lea.l    (a0,d0.l),a1      * a1 points (perhaps) to 'magic' in old
  221.       move.l   #(magicend-magic-1),d0 * # chars in 'magic' string minus one
  222. chkmag
  223.       cmp.b    (a0)+,(a1)+       * Check strings for equality
  224.       dbne     d0,chkmag
  225.